package capricornus.components.guide
{
	import capricornus.actor.utils.Direction;
	import capricornus.components.ComponentsManager;
	import capricornus.components.utils.FilterUtils;
	import capricornus.core.ClassManager;
	import capricornus.core.StageManager;
	import capricornus.events.StageEvent;
	import capricornus.utils.roughtime.RoughTimer;
	import capricornus.utils.roughtime.RoughTimerEvent;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Dictionary;
	import flash.utils.setTimeout;

	/**
	 * 新手引导指针 
	 * @author kael
	 * 
	 */	
	public class GuideManager
	{
		private static var _ins:GuideManager = null;
		
		private var _dict:Dictionary;
		private var _layer:Sprite;
		private var _timer:RoughTimer;
		
		private var _followTimer:RoughTimer;
		
		public function GuideManager()
		{
			init();
		}
		
		public static function get instance():GuideManager
		{
			if( _ins==null )
			{
				_ins = new GuideManager();
			}
			return _ins;
		}
		
		private function init():void
		{
			_dict = new Dictionary();
			
			_layer = new Sprite();
			_layer.mouseChildren = false;
			_layer.mouseEnabled = false;
			ComponentsManager.instance.alertLayer.addChild( _layer );
			
			_timer = new RoughTimer(40, 1);
			_timer.addEventListener( RoughTimerEvent.TIMER, onRoughTimer, false, 0, true );
			
			_followTimer = new RoughTimer( 300 );
			_followTimer.addEventListener( RoughTimerEvent.TIMER, onFollow, false, 0, true );
		}
		
		/**
		 * 显示指针指向dis 
		 * @param dis
		 * @param direct 指针相对dis的方向
		 * 
		 */		
		public function showIndicate( dis:DisplayObject, direct:int=Direction.LEFT, followHtml:String="" ):void
		{
			if( dis != null && _dict[dis]==null )
			{
				_dict[dis] = [dis, direct, null, getFollowTips(followHtml)];
				setTimeout( indicate, 40, dis, direct );
			}
		}
		
		public function resizeIndicate( dis:DisplayObject ):void
		{
			var arr:Array;
			if( (arr=_dict[dis]) != null )
			{
				if( arr.length==4 )
				{
					resizeIndicator( arr[0], arr[2], arr[1] );
					resizeTips( arr[0], arr[3], arr[1] );
				}
			}
		}
		
		public function clearIndicate( dis:DisplayObject ):void
		{
			var arr:Array;
			if( (arr=_dict[dis]) != null )
			{
				delete _dict[dis];
				var mc:MovieClip = arr[2];
				if( mc != null )
				{
					if( mc.parent != null )
					{
						mc.parent.removeChild( mc );
					}
					mc.stop();
				}
				var tip:DisplayObject = arr[3];
				if( tip != null )
				{
					if( tip.parent != null )
					{
						tip.parent.removeChild( tip );
					}
				}
				arr.length = 0;
				if( dis.hasEventListener( Event.REMOVED_FROM_STAGE ) )
					dis.removeEventListener( Event.REMOVED_FROM_STAGE, onRemoveFromStage );
			}
			if( _layer.numChildren==0 )
			{
				removeResizeListener();
			}
		}
		
		private function getFollowTips( tips:String ):Sprite
		{
			if( tips=="" || tips==null ) return null;
			var s:Sprite = ClassManager.getClassInstance("mcTooltipPanel") as Sprite;
			var txt:TextField = new TextField();
			txt.defaultTextFormat = new TextFormat("microsoft yahei",12);
			txt.filters = FilterUtils.getBlackGlowFilter();
			txt.multiline = true;
			txt.htmlText = tips;
			txt.width = txt.textWidth + 4;
			txt.height = txt.textHeight + 4;
			
			s.width = txt.width + 4;
			s.height = txt.height + 4;
			txt.x = txt.y = 2;
			
			var mc:Sprite = new Sprite();
			mc.addChild( s );
			mc.addChild( txt );
			
			return mc;
		}
		
		private var _hasAddResize:Boolean = false;
		private function addResizeListener():void
		{
			if( !_hasAddResize )
			{
				_followTimer.reset();
				_followTimer.start();
				StageManager.instance.addEventListener( StageEvent.RESIZE, onResize, false, -10, true );
			}
		}
		
		private function removeResizeListener():void
		{
			if( _hasAddResize )
			{
				_hasAddResize = false;
				_followTimer.stop();
				StageManager.instance.removeEventListener( StageEvent.RESIZE, onResize );
			}
		}
		
		private function onFollow( e:RoughTimerEvent ):void
		{
			onResize( null );
		}
		
		private function indicate( dis:DisplayObject, direct:int ):void
		{
			_layer.parent.setChildIndex( _layer, _layer.parent.numChildren-1 );
			
			if( dis.stage != null && _dict[dis] != null && (_dict[dis] as Array)[2]==null )
			{
				var rect:Rectangle = dis.getBounds( _layer );
				
				var mc:Sprite = ClassManager.getClassInstance( "GuideIndicatorPanel" ) as Sprite;
				resizeIndicator( dis, mc, direct );
				resizeTips( dis, (_dict[dis] as Array)[3], direct );
				_layer.addChild( mc );
				if( (_dict[dis] as Array)[3] != null )
				{
					_layer.addChild( (_dict[dis] as Array)[3] );
				}
				(_dict[dis] as Array)[2] = mc;
				
				var vis:DisplayObjectContainer = dis.parent
				mc.visible = vis.visible
				addResizeListener();
				dis.addEventListener( Event.REMOVED_FROM_STAGE, onRemoveFromStage, false, 0, true );
			}
			else
			{
				clearIndicate( dis );
			}
		}
		
		private function resizeIndicator( dis:DisplayObject, mc:DisplayObject, direct:int ):void
		{
			if( mc==null ) return;
			
			var rect:Rectangle = dis.getBounds( _layer );
			if( direct==Direction.RIGHT )
			{
				//右
				mc.rotation = 180;
				mc.x = int(rect.x + rect.width + 10);
				mc.y = int(rect.y + rect.height/2);
			}
			else if( direct==Direction.DOWN )
			{
				//下
				mc.rotation = -90;
				mc.x = int(rect.x + rect.width/2);
				mc.y = int(rect.y + rect.height + 10);
			}
			else if( direct==Direction.UP )
			{
				//上
				mc.rotation = 90;
				mc.x = int(rect.x + rect.width/2);
				mc.y = int(rect.y - 10);
			}
			else
			{
				//左
				mc.x = int(rect.x - 10);
				mc.y = int(rect.y + rect.height/2);
			}
		}
		
		private function resizeTips( dis:DisplayObject, tip:DisplayObject, direct:int ):void
		{
			if( tip==null ) return;
			
			var rect:Rectangle = dis.getBounds( _layer );
			if( direct==Direction.RIGHT )
			{
				//右
				tip.x = int(rect.x + rect.width + 90);
				tip.y = int(rect.y + rect.height/2 - tip.height/2);
			}
			else if( direct==Direction.DOWN )
			{
				//下
				tip.x = int(rect.x + rect.width/2 - tip.width/2);
				tip.y = int(rect.y + rect.height + 90);
			}
			else if( direct==Direction.UP )
			{
				//上
				tip.x = int(rect.x + rect.width/2 - tip.width/2);
				tip.y = int(rect.y - 90);
			}
			else
			{
				//左
				tip.x = int(rect.x - 90);
				tip.y = int(rect.y + rect.height/2 - tip.height/2);
			}
		}
		
		private function onRemoveFromStage( e:Event ):void
		{
			var dis:DisplayObject = e.currentTarget as DisplayObject;
			clearIndicate( dis );
		}
		
		private function onResize( e:StageEvent ):void
		{
			for( var i:* in _dict )
			{
				var arr:Array = _dict[i];
				if( arr.length==4 )
				{
					resizeIndicator( arr[0], arr[2], arr[1] );
					resizeTips( arr[0], arr[3], arr[1] );
				}
			}
			if( e != null )
			{
				_timer.reset();
				_timer.start();
			}
		}
		
		private function onRoughTimer( e:RoughTimerEvent ):void
		{
			for( var i:* in _dict )
			{
				var arr:Array = _dict[i];
				if( arr.length==4 )
				{
					resizeIndicator( arr[0], arr[2], arr[1] );
					resizeTips( arr[0], arr[3], arr[1] );
				}
			}
		}
	}
}











